package com.viviet.mobileservices.web.action;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.opensymphony.xwork2.ModelDriven;
import com.viviet.mobileservices.business.ICustomerService;
import com.viviet.mobileservices.business.IMessageService;
import com.viviet.mobileservices.business.exception.OperationException;
import com.viviet.mobileservices.common.BaseAction;
import com.viviet.mobileservices.common.Constants;
import com.viviet.mobileservices.domain.info.BalanceInfo;
import com.viviet.mobileservices.domain.info.MessageInfo;
import com.viviet.mobileservices.domain.info.QRCodeInfo;
import com.viviet.mobileservices.domain.info.TransactionInfo;
import com.viviet.mobileservices.domain.model.CustomerModel;
import com.viviet.mobileservices.util.Logit;
import com.viviet.mobileservices.util.Utilities;
import com.viviet.sentMT.MessageOut;
import com.viviet.sentMT.viviet_sent_mt;

public class CustomerAction extends BaseAction implements ModelDriven<CustomerModel> {
	private final Logit LOG = Logit.getInstance(CustomerAction.class);
	private static final long serialVersionUID = -4606720304727321826L;
	private ICustomerService customerService;
	private IMessageService messageService;
	private CustomerModel model = new CustomerModel();
	private MessageInfo msg;

	/**
	 * @param customerService the customerService to set
	 */
	public void setCustomerService(ICustomerService customerService) {
		this.customerService = customerService;
	}

	/**
	 * @param messageService the messageService to set
	 */
	public void setMessageService(IMessageService messageService) {
		this.messageService = messageService;
	}


	public CustomerModel getModel() {
		return this.model;
	}

	/**
	 * Get balance of a account
	 * @return
	 */
	public String getBalance() {
		MessageInfo msg = null;
		try { 
			this.model.setBalanceInfo(customerService.getBalance(model));
		} catch(OperationException ex) {
			msg = ex.getMsg();
			msg.setMsgContent(getText(messageService.getMessage(msg.getMsgCode())));
		}
		
		setMsg(msg);
		return SUCCESS;
	}

	/**
	 * Transfer money from an account to another one
	 * @return Message
	 */
	public String transferMoney() {
		msg = createMessage(Constants.OPERATION_SUCCESS, Constants.TRAN_SUCCESS, null);
		
		try {
			msg = customerService.transferMoney(model);
		} catch (OperationException ex) {
			msg = ex.getMsg();
		}
		
		//convert message code to message via message service
		msg.setMsgContent(getText(messageService.getMessage(msg.getMsgContent())));
		setMsg(msg);
		
		return SUCCESS;
	}

	/**
	 * Change password for viviet account not mobile account
	 * @return
	 */
	public String changePassword() {
		msg  = customerService.changePassword(Utilities.getWebUserDetails().getUser().getCustomerId(),model.getOld_password(), model.getNew_password());
		
		//convert message code to message via message service
		msg.setMsgContent(getText(messageService.getMessage(msg.getMsgContent())));
		setMsg(msg);
		
		return SUCCESS;
	}

	public String getTransactionsInfo() {
		setMsg(createMessage(0, "GT001", "msg.get_transaction_info_success"));

		List trans = new ArrayList();

		for (int i = 0; i < 10; i++) {
			TransactionInfo tran = new TransactionInfo();
			tran.setAmount(Long.valueOf(Double.valueOf(Math.random() * 1000000.0D).longValue()));
			tran.setReceiver("1234567890");
			tran.setSender("0987654321");
			tran.setTransactionDate(new Date(System.currentTimeMillis() - Double.valueOf(Math.random() * 10000000.0D).longValue()));
			tran.setTransactionType(i % 2);

			trans.add(tran);
		}

		this.model.setListTransactions(trans);
		return SUCCESS;
	}
	
	/**
	 * Get payment detail information
	 * @return
	 */
	public String getQRCodeInfo() {
		msg = createMessage(Constants.OPERATION_SUCCESS, Constants.QR_GET_SUCCESS, null);
		try {
			model.setQrCodeInfo(customerService.findQRCodeDetailInfo(model.getQrCodeId()));
		} catch (OperationException ex) {
			msg = ex.getMsg();
		}
		
		//convert message code to message via message service
		msg.setMsgContent(getText(messageService.getMessage(msg.getMsgContent())));
		
		setMsg(msg);
		return SUCCESS;
	}
	
	/**
	 * Create payment bill
	 * @return
	 */
	public String generateQRCode() {
		// generate QR code
		msg = createMessage(Constants.OPERATION_SUCCESS, Constants.QR_CREATE_SUCCESS, null);
		try {
			QRCodeInfo code = customerService.generateQRCode(model);
			model.setQrCodeInfo(code);
		} catch (OperationException ex) {
			msg = ex.getMsg();
		}
		
		//convert message code to message via message service
		msg.setMsgContent(getText(messageService.getMessage(msg.getMsgContent())));
		setMsg(msg);
		
		return SUCCESS;
	}
	
	/**
	 * Register new Account
	 * @return
	 */
	public String registerAccount() {
		try {
			msg = customerService.registerUser(model);
		} catch (OperationException ex) {
			LOG.debug("Error in registration user",ex);
		}
		
		//convert message code to message via message service
		msg.setMsgContent(getText(messageService.getMessage(msg.getMsgContent())));
		setMsg(msg);
		
		return SUCCESS;
	}
	
	public String confirmTransaction() {
		// TODO: integration with hard token
		
		MessageInfo msg = createMessage(Constants.OPERATION_SUCCESS, "TM001", "msg.transfer_money_complete");
		setMsg(msg);
		return SUCCESS;
	}
	
	public String processMessages() {
		
		viviet_sent_mt smsProvider = new viviet_sent_mt();
//		MessageOut out = smsProvider.sentMT("84936376736", "test mt");
		
		String sender = model.getSender();
		String smsCommand = model.getCommand();
		
		model.setSMSChannel(true);
		
		LOG.debug("### SMS SENDER: "+sender);
		LOG.debug("### SMS MESSAGE: "+smsCommand);
		
		String retValue = null;
		if (smsCommand != null && smsCommand.startsWith("MA")) {
			String sms[] = smsCommand.split(" ");
			LOG.debug("### SMS "+sms[1]);
			// get balance
			if ("SD".equals(sms[1])) {
				try {
					model.setJ_password(sms[2]);
					BalanceInfo balance = customerService.getBalance(model);
					retValue = "00|"+balance.getBalance()+"|"+getText(Constants.GET_BALANCE_SUCCESS);
				} catch (OperationException ex) {
					MessageInfo msg = ex.getMsg();
					retValue = "01||"+getText(msg.getMsgContent());
				} catch (Exception ex) {
					retValue = "01||"+getText(Constants.GET_BALANCE_FAILED);
				}
			} 
			// transfer money
			else if ("CT".equals(sms[1])) {
				try {
					model.setJ_password(sms[4]);
					model.setAmount(Integer.valueOf(sms[3]));
					model.setReceiver(sms[2]);
					model.setSMSChannel(true);
					
					MessageInfo msg = customerService.transferMoney(model);
					retValue = "00|"+getText(msg.getMsgContent());
				} catch (OperationException ex) {
					MessageInfo msg = ex.getMsg();
					retValue = "01|"+getText(msg.getMsgContent());
				} catch (Exception ex) {
					retValue = "01||"+getText(Constants.TRAN_FAILED);
				}
			} 
			// confirm transaction
			else if ("CF".equals(sms[1])) {
				
			}
			// generateQRCode
			else if ("TQR".equals(sms[1])) {
				try {
					msg = createMessage(Constants.OPERATION_SUCCESS, Constants.QR_CREATE_SUCCESS, null);
					model.setJ_password(sms[4]);
					model.setAmount(Integer.valueOf(sms[3]));
					model.setReceiver(sms[2]);
					model.setSMSChannel(true);
					
					QRCodeInfo code = customerService.generateQRCode(model);
					
					retValue = "00|"+code.getId()+"|"+getText(messageService.getMessage(msg.getMsgContent()));
				} catch (OperationException ex) {
					msg = ex.getMsg();
					retValue = "01||"+getText(messageService.getMessage(msg.getMsgContent()));
				} catch (Exception ex) {
					retValue = "01||"+getText(Constants.TRAN_FAILED);
				}
			}
			// get QR code
			else if ("GQR".equals(sms[1])) {
				try {
					msg = createMessage(Constants.OPERATION_SUCCESS, Constants.QR_GET_SUCCESS, null);
					QRCodeInfo code = customerService.findQRCodeDetailInfo(sms[2]);
					
					retValue = "00|"+code.getReceiver()+","+code.getAmount()+"|"+getText(messageService.getMessage(msg.getMsgContent()));
				} catch (OperationException ex) {
					msg = ex.getMsg();
					retValue = "01||"+getText(messageService.getMessage(msg.getMsgContent()));
				} catch (Exception ex) {
					retValue = "01||"+getText(Constants.TRAN_FAILED);
				}
			}
			// changepassword
			else if  ("MK".equals(sms[1])) {
				msg  = customerService.changePassword(sender, sms[2], sms[3]);
				
				retValue = (msg.getMsgType() == Constants.OPERATION_SUCCESS? "00|":"01|")+getText(messageService.getMessage(msg.getMsgContent()));
			}
			
			// register
			else if  ("DK".equals(sms[1])) {
				model.setUserName(sms[2]);
				model.setPassword(sms[3]);
				model.setVivietAcc(sms[4]);
				
				try {
					msg = customerService.registerUser(model);
				} catch (OperationException ex) {
					LOG.debug("Error in registration user",ex);
				}
				
				//convert message code to message via message service
				msg.setMsgContent(getText(messageService.getMessage(msg.getMsgContent())));
				
				retValue = (msg.getMsgType() == Constants.OPERATION_SUCCESS? "00|":"01|")+getText(messageService.getMessage(msg.getMsgContent()));
			} 
			
			else {
				retValue = "01|"+getText(Constants.INVALID_REQUEST);
			}
			
		} else {
			retValue = "01|"+getText(Constants.SYSTEM_ERROR);
		}
		
		
		// send result sms to sender
		MessageOut smsOut =  smsProvider.sentMT(sender, retValue);
		
		LOG.debug("SMS return: "+smsOut.toString());
		
		return SUCCESS;
	}

	public MessageInfo getMsg() {
		return this.msg;
	}

	public void setMsg(MessageInfo msg) {
		this.msg = msg;
	}
}